/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright 2015 Garrett D'Amore <garrett@damore.org>
 * Copyright 2016 Joyent, Inc.
 * Copyright 2023 Oxide Computer Company
 */

#ifndef	_SYS_MAC_ETHER_H
#define	_SYS_MAC_ETHER_H

/*
 * Ethernet MAC Plugin
 */

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * Ethernet-specific media types for use with MAC_PROP_MEDIA and
 * ETHER_STAT_XCVR_INUSE. See mac(9E) for more information.
 */
typedef enum {
	ETHER_MEDIA_UNKNOWN	= 0,
	ETHER_MEDIA_NONE,
	ETHER_MEDIA_10BASE_T,
	ETHER_MEDIA_100BASE_T4,
	/*
	 * 100BASE-X is a catchall term defined in 802.3. In 802.3 section
	 * 24.1.1 100BASE-X is used to cover the more specific 100BASE-TX and
	 * 100BASE-FX realized in copper and fiber. The PCS is shared between
	 * the two, but the PMD is different. Use this if you can't determine TX
	 * vs. FX.
	 */
	ETHER_MEDIA_100BASE_X,
	/*
	 * Note, previously there was never a 100BASE-TX value so some drivers
	 * would have returned this for 100BASE-TX.
	 */
	ETHER_MEDIA_100BASE_T2,
	/*
	 * 1000BASE-X is a fiber catch all. This is for compatibility with the
	 * traditional ETHER_STAT_XCVR_INUSE 1000BASE-X value. More specific
	 * variants are listed below. USe this if nothing more specific is
	 * feasible.
	 */
	ETHER_MEDIA_1000BASE_X,
	ETHER_MEDIA_1000BASE_T,
	ETHER_MEDIA_1000BASE_KX,
	ETHER_MEDIA_1000BASE_T1,
	ETHER_MEDIA_1000BASE_CX,
	ETHER_MEDIA_1000BASE_SX,
	ETHER_MEDIA_1000BASE_LX,
	ETHER_MEDIA_1000BASE_BX,
	ETHER_MEDIA_1000_SGMII,

	/*
	 * Additional more recent or erroneously skipped 10/100 modes.
	 */
	ETHER_MEDIA_100BASE_TX,
	ETHER_MEDIA_100BASE_FX,
	ETHER_MEDIA_100_SGMII,
	ETHER_MEDIA_10BASE_T1,
	ETHER_MEDIA_100BASE_T1,

	/*
	 * 2.5 GbE, 5.0 GbE, single lane.
	 */
	ETHER_MEDIA_2500BASE_T,
	ETHER_MEDIA_2500BASE_KX,
	ETHER_MEDIA_2500BASE_X,
	ETHER_MEDIA_5000BASE_T,
	ETHER_MEDIA_5000BASE_KR,

	/*
	 * 10 GbE, all lane configurations.
	 */
	ETHER_MEDIA_10GBASE_T,
	ETHER_MEDIA_10GBASE_SR,
	ETHER_MEDIA_10GBASE_LR,
	ETHER_MEDIA_10GBASE_LRM,
	ETHER_MEDIA_10GBASE_KR,
	ETHER_MEDIA_10GBASE_CX4,
	ETHER_MEDIA_10GBASE_KX4,
	ETHER_MEDIA_10G_XAUI,
	ETHER_MEDIA_10GBASE_AOC,
	ETHER_MEDIA_10GBASE_ACC,
	ETHER_MEDIA_10GBASE_CR,
	ETHER_MEDIA_10GBASE_ER,
	ETHER_MEDIA_10G_SFI,
	ETHER_MEDIA_10G_XFI,

	/*
	 * 25 GbE, single lane.
	 */
	ETHER_MEDIA_25GBASE_T,
	ETHER_MEDIA_25GBASE_SR,
	ETHER_MEDIA_25GBASE_LR,
	ETHER_MEDIA_25GBASE_ER,
	ETHER_MEDIA_25GBASE_KR,
	ETHER_MEDIA_25GBASE_CR,
	ETHER_MEDIA_25GBASE_AOC,
	ETHER_MEDIA_25GBASE_ACC,
	ETHER_MEDIA_25G_AUI,

	/*
	 * 40 GbE based on 10 GbE
	 */
	ETHER_MEDIA_40GBASE_T,
	ETHER_MEDIA_40GBASE_CR4,
	ETHER_MEDIA_40GBASE_KR4,
	ETHER_MEDIA_40GBASE_LR4,
	ETHER_MEDIA_40GBASE_SR4,
	ETHER_MEDIA_40GBASE_ER4,
	ETHER_MEDIA_40GBASE_LM4,
	ETHER_MEDIA_40GBASE_AOC4,
	ETHER_MEDIA_40GBASE_ACC4,
	ETHER_MEDIA_40G_XLAUI,
	ETHER_MEDIA_40G_XLPPI,

	/*
	 * 50 GbE based on 25 GbE
	 */
	ETHER_MEDIA_50GBASE_KR2,
	ETHER_MEDIA_50GBASE_CR2,
	ETHER_MEDIA_50GBASE_SR2,
	ETHER_MEDIA_50GBASE_LR2,
	ETHER_MEDIA_50GBASE_AOC2,
	ETHER_MEDIA_50GBASE_ACC2,

	/*
	 * 50 GbE based on 50 GbE PAM4
	 */
	ETHER_MEDIA_50GBASE_KR,
	ETHER_MEDIA_50GBASE_CR,
	ETHER_MEDIA_50GBASE_SR,
	ETHER_MEDIA_50GBASE_LR,
	ETHER_MEDIA_50GBASE_FR,
	ETHER_MEDIA_50GBASE_ER,
	ETHER_MEDIA_50GBASE_AOC,
	ETHER_MEDIA_50GBASE_ACC,

	/*
	 * 100 GbE based on 10 GbE
	 */
	ETHER_MEDIA_100GBASE_CR10,
	ETHER_MEDIA_100GBASE_SR10,

	/*
	 * 100 GbE based on 25 GbE
	 */
	ETHER_MEDIA_100GBASE_SR4,
	ETHER_MEDIA_100GBASE_LR4,
	ETHER_MEDIA_100GBASE_ER4,
	ETHER_MEDIA_100GBASE_KR4,
	ETHER_MEDIA_100GBASE_CR4,
	ETHER_MEDIA_100GBASE_CAUI4,
	ETHER_MEDIA_100GBASE_AOC4,
	ETHER_MEDIA_100GBASE_ACC4,

	/*
	 * 100 GbE based on 50 GbE
	 */
	ETHER_MEDIA_100GBASE_KR2,
	ETHER_MEDIA_100GBASE_CR2,
	ETHER_MEDIA_100GBASE_SR2,

	/*
	 * 100 GbE based on 100 GbE
	 */
	ETHER_MEDIA_100GBASE_KR,
	ETHER_MEDIA_100GBASE_CR,
	ETHER_MEDIA_100GBASE_SR,
	ETHER_MEDIA_100GBASE_DR,
	ETHER_MEDIA_100GBASE_LR,
	ETHER_MEDIA_100GBASE_FR,

	/*
	 * 200G Ethernet based on 50 GbE
	 */
	ETHER_MEDIA_200GAUI_4,
	ETHER_MEDIA_200GBASE_CR4,
	ETHER_MEDIA_200GBASE_KR4,
	ETHER_MEDIA_200GBASE_SR4,
	ETHER_MEDIA_200GBASE_DR4,
	ETHER_MEDIA_200GBASE_FR4,
	ETHER_MEDIA_200GBASE_LR4,
	ETHER_MEDIA_200GBASE_ER4,

	/*
	 * 200G Ethernet based on 100 GbE
	 */
	ETHER_MEDIA_200GAUI_2,
	ETHER_MEDIA_200GBASE_KR2,
	ETHER_MEDIA_200GBASE_CR2,
	ETHER_MEDIA_200GBASE_SR2,

	/*
	 * 400G based on 50 GbE
	 */
	ETHER_MEDIA_400GAUI_8,
	ETHER_MEDIA_400GBASE_KR8,
	ETHER_MEDIA_400GBASE_FR8,
	ETHER_MEDIA_400GBASE_LR8,
	ETHER_MEDIA_400GBASE_ER8,

	/*
	 * 400G based on 100 GbE
	 */
	ETHER_MEDIA_400GAUI_4,
	ETHER_MEDIA_400GBASE_KR4,
	ETHER_MEDIA_400GBASE_CR4,
	ETHER_MEDIA_400GBASE_SR4,
	ETHER_MEDIA_400GBASE_DR4,
	ETHER_MEDIA_400GBASE_FR4
} mac_ether_media_t;

#ifdef	_KERNEL

#define	MAC_PLUGIN_IDENT_ETHER	"mac_ether"

/*
 * Do not reorder, and add only to the end of this list.
 */
enum ether_stat {
	/* RFC 1643 stats */
	ETHER_STAT_ALIGN_ERRORS = MACTYPE_STAT_MIN,
	ETHER_STAT_FCS_ERRORS,
	ETHER_STAT_FIRST_COLLISIONS,
	ETHER_STAT_MULTI_COLLISIONS,
	ETHER_STAT_SQE_ERRORS,
	ETHER_STAT_DEFER_XMTS,
	ETHER_STAT_TX_LATE_COLLISIONS,
	ETHER_STAT_EX_COLLISIONS,
	ETHER_STAT_MACXMT_ERRORS,
	ETHER_STAT_CARRIER_ERRORS,
	ETHER_STAT_TOOLONG_ERRORS,
	ETHER_STAT_MACRCV_ERRORS,

	/* MII/GMII stats */
	ETHER_STAT_XCVR_ADDR,
	ETHER_STAT_XCVR_ID,
	ETHER_STAT_XCVR_INUSE,
	ETHER_STAT_CAP_1000FDX,
	ETHER_STAT_CAP_1000HDX,
	ETHER_STAT_CAP_100FDX,
	ETHER_STAT_CAP_100HDX,
	ETHER_STAT_CAP_10FDX,
	ETHER_STAT_CAP_10HDX,
	ETHER_STAT_CAP_ASMPAUSE,
	ETHER_STAT_CAP_PAUSE,
	ETHER_STAT_CAP_AUTONEG,
	ETHER_STAT_ADV_CAP_1000FDX,
	ETHER_STAT_ADV_CAP_1000HDX,
	ETHER_STAT_ADV_CAP_100FDX,
	ETHER_STAT_ADV_CAP_100HDX,
	ETHER_STAT_ADV_CAP_10FDX,
	ETHER_STAT_ADV_CAP_10HDX,
	ETHER_STAT_ADV_CAP_ASMPAUSE,
	ETHER_STAT_ADV_CAP_PAUSE,
	ETHER_STAT_ADV_CAP_AUTONEG,
	ETHER_STAT_LP_CAP_1000FDX,
	ETHER_STAT_LP_CAP_1000HDX,
	ETHER_STAT_LP_CAP_100FDX,
	ETHER_STAT_LP_CAP_100HDX,
	ETHER_STAT_LP_CAP_10FDX,
	ETHER_STAT_LP_CAP_10HDX,
	ETHER_STAT_LP_CAP_ASMPAUSE,
	ETHER_STAT_LP_CAP_PAUSE,
	ETHER_STAT_LP_CAP_AUTONEG,
	ETHER_STAT_LINK_ASMPAUSE,
	ETHER_STAT_LINK_PAUSE,
	ETHER_STAT_LINK_AUTONEG,
	ETHER_STAT_LINK_DUPLEX,

	ETHER_STAT_TOOSHORT_ERRORS,
	ETHER_STAT_CAP_REMFAULT,
	ETHER_STAT_ADV_REMFAULT,
	ETHER_STAT_LP_REMFAULT,

	ETHER_STAT_JABBER_ERRORS,
	ETHER_STAT_CAP_100T4,
	ETHER_STAT_ADV_CAP_100T4,
	ETHER_STAT_LP_CAP_100T4,

	ETHER_STAT_CAP_10GFDX,
	ETHER_STAT_ADV_CAP_10GFDX,
	ETHER_STAT_LP_CAP_10GFDX,

	ETHER_STAT_CAP_40GFDX,
	ETHER_STAT_ADV_CAP_40GFDX,
	ETHER_STAT_LP_CAP_40GFDX,

	ETHER_STAT_CAP_100GFDX,
	ETHER_STAT_ADV_CAP_100GFDX,
	ETHER_STAT_LP_CAP_100GFDX,

	ETHER_STAT_CAP_2500FDX,
	ETHER_STAT_ADV_CAP_2500FDX,
	ETHER_STAT_LP_CAP_2500FDX,

	ETHER_STAT_CAP_5000FDX,
	ETHER_STAT_ADV_CAP_5000FDX,
	ETHER_STAT_LP_CAP_5000FDX,

	ETHER_STAT_CAP_25GFDX,
	ETHER_STAT_ADV_CAP_25GFDX,
	ETHER_STAT_LP_CAP_25GFDX,

	ETHER_STAT_CAP_50GFDX,
	ETHER_STAT_ADV_CAP_50GFDX,
	ETHER_STAT_LP_CAP_50GFDX,

	ETHER_STAT_CAP_200GFDX,
	ETHER_STAT_ADV_CAP_200GFDX,
	ETHER_STAT_LP_CAP_200GFDX,

	ETHER_STAT_CAP_400GFDX,
	ETHER_STAT_ADV_CAP_400GFDX,
	ETHER_STAT_LP_CAP_400GFDX,
};

#define	ETHER_NSTAT	\
	(ETHER_STAT_LP_CAP_400GFDX - ETHER_STAT_ALIGN_ERRORS + 1)

#define	ETHER_STAT_ISACOUNTER(_ether_stat)				\
	    ((_ether_stat) == ETHER_STAT_ALIGN_ERRORS ||		\
		(_ether_stat) == ETHER_STAT_FCS_ERRORS ||		\
		(_ether_stat) == ETHER_STAT_FIRST_COLLISIONS ||		\
		(_ether_stat) == ETHER_STAT_MULTI_COLLISIONS ||		\
		(_ether_stat) == ETHER_STAT_SQE_ERRORS ||		\
		(_ether_stat) == ETHER_STAT_DEFER_XMTS ||		\
		(_ether_stat) == ETHER_STAT_TX_LATE_COLLISIONS ||	\
		(_ether_stat) == ETHER_STAT_EX_COLLISIONS ||		\
		(_ether_stat) == ETHER_STAT_MACXMT_ERRORS ||		\
		(_ether_stat) == ETHER_STAT_CARRIER_ERRORS ||		\
		(_ether_stat) == ETHER_STAT_TOOLONG_ERRORS ||		\
		(_ether_stat) == ETHER_STAT_TOOSHORT_ERRORS ||		\
		(_ether_stat) == ETHER_STAT_JABBER_ERRORS ||		\
		(_ether_stat) == ETHER_STAT_MACRCV_ERRORS)

#endif	/* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif /* _SYS_MAC_ETHER_H */
